/**
 * 
 */
package com.songlanyun.common.kqUtils.tr;

import org.apache.commons.io.IOUtils;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import java.io.UnsupportedEncodingException;
import java.net.SocketTimeoutException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
/**
 * @author wenlin.tan
 *
 */
public class HttpUtil {

//	protected static Logger LOGGER = LoggerFactory.getLogger(HttpUtil.class);
	/** 默认读取超时时间 （单位毫秒） */
	private static final int DEFAULT_SOCKET_TIMEOUT = 8 * 1000;

	/** 默认连接超时时间（单位毫秒） */
	private static final int DEFAULT_CONNECT_TIMEOUT = 3 * 1000;

	private static PoolingHttpClientConnectionManager connManager;

	static{
		try {
			SSLContext sslcontext = createIgnoreVerifySSL();
			Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder
					.<ConnectionSocketFactory> create().register("http", PlainConnectionSocketFactory.INSTANCE)
					.register("https", new SSLConnectionSocketFactory(sslcontext)).build();
			connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException("[ Https init connectionManager faild !! ]",e);
		}
	}


	/**
	 * 绕过验证
	 * @return
	 * @throws NoSuchAlgorithmException
	 * @throws KeyManagementException
	 */
	private static SSLContext createIgnoreVerifySSL() throws NoSuchAlgorithmException, KeyManagementException {
		SSLContext sc = SSLContext.getInstance("TLSv1.2");
		// 实现一个X509TrustManager接口，用于绕过验证，不用修改里面的方法
		X509TrustManager trustManager = new X509TrustManager() {

			public void checkClientTrusted(java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
										   String paramString) throws CertificateException {}


			public void checkServerTrusted(java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
										   String paramString) throws CertificateException {}


			public java.security.cert.X509Certificate[] getAcceptedIssuers() {
				return null;
			}
		};
		sc.init(null, new TrustManager[] { trustManager }, null);
		return sc;
	}
	/**
	 * Http request ：Post
	 *
	 * @param url
	 * (Millisecond)
	 * @return result map
	 */
	public static String postHttpRequest(String requestString, String url,String encode)
			throws Exception {
		return postHttpRequest(requestString, url, encode,DEFAULT_CONNECT_TIMEOUT,
				DEFAULT_SOCKET_TIMEOUT);
	}


	/**
	 * Http request ：Post
	 *
	 * @param url
	 * (Millisecond)
	 * @return result map
	 */
	public static String postHttpRequest(String url,String reqeustString, String encode,
										 int connectTimeout, int socketTimeOut) throws Exception {

		CloseableHttpResponse response = null;
		try {
			if(reqeustString!=null){
				reqeustString = changeCharset(reqeustString,encode);
			}else{
				reqeustString = "[]";
			}
			HttpPost httpPost = new HttpPost(url);
			httpPost.addHeader("Content-Type", "application/json;charset=UTF-8");
			// 连接池超时时间使用connect超时时间
			RequestConfig requestConfig = RequestConfig.custom()
					.setConnectionRequestTimeout(connectTimeout)
					.setConnectTimeout(connectTimeout)
					.setSocketTimeout(socketTimeOut).build();
			httpPost.setConfig(requestConfig);
			httpPost.setEntity(new StringEntity(reqeustString, "UTF-8"));
			response = HttpConnectionManager.getHttpClient(requestConfig).execute(httpPost);
			// get http status code
			int resStatu = response.getStatusLine().getStatusCode();
			String responseString = null;
			if (resStatu == HttpStatus.SC_OK) {
				responseString = IOUtils.toString(response.getEntity()
						.getContent(), "UTF-8");
			} else {
				
				throw new Exception(url + ",the statusCode is " + resStatu);
			}
			return responseString;
		} catch (ConnectTimeoutException e) {
			e.printStackTrace();
			throw e;
		} catch (SocketTimeoutException e) {
			e.printStackTrace();
			throw e;
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		} finally {
			if (response != null) {
				try {
					EntityUtils.consume(response.getEntity());
					response.close();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}

	/**
	 * 字符串编码转换的实现方法
	 * 
	 * @param str
	 *            待转换编码的字符串
	 * @param newCharset
	 *            目标编码
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static String changeCharset(String str, String newCharset)
			throws UnsupportedEncodingException {
		// 用默认字符编码解码字符串。
		byte[] bs = str.getBytes();
		// 用新的字符编码生成字符串
		return new String(bs, newCharset);
	}

}
